package com.dcivision.workflow.utility;

import java.io.FileNotFoundException;
import java.io.IOException;

import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;

import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.Utility;
import com.dcivision.user.bean.UserDelegation;
import com.dcivision.user.bean.UserGroup;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.bean.WorkflowStep;

/**
 * this Class is a Object Factory that Build some Workflow Object has some
 * attribute but no ID
 * 
 * 
 * @author Samlin.zhang
 */
public class WFObjectFactory {

    private static final String EIP318STANDARD_DELETE_ALL_FOR_BASE_TEST_XML = "/dbunit/eip318StandardDeleteAllForBaseTest.xml";

    private static IDataSet deleteAllDataset;

    private static IDataSet deleteAllForBaseTestDataSet;

    private static IDataSet allInitWorkflowEnvTestDataSet;

    /**
     * get a new WorkflowRecord and Setup some default attribute
     * 
     * @author Samlin.zhang
     * @param workflowCode
     * @return a new WorkflowRecord but no ID
     */
    public static WorkflowRecord getNewWorkflowRecord(String workflowCode) {
        WorkflowRecord workflow = new WorkflowRecord();
        workflow.setWorkflowCode(workflowCode);
        workflow.setWorkflowVersion("1");
        workflow.setWorkflowGroupID(new Integer("1"));
        workflow.setDescription("this is test workflow Description");
        workflow.setAllowInterrupt(GlobalConstant.FALSE);
        workflow.setInterruptWorkflowRecordID(null);
        workflow.setWorkflowCategoryID(new Integer("1"));
        workflow.setParentID(null);
        workflow.setStatus("P");
        workflow.setStartDate(Utility.getCurrentTimestamp());
        return workflow;
    }

    /**
     * get a new WorkflowStep and Setup some default attribute
     * 
     * @author Samlin.zhang
     * @param workflowID
     * @param parentStepID
     * @param currentStepID
     * @param allPermissionData
     * @param stepSeq
     * @return a new WorkflwRecord
     */
    public static WorkflowStep getNewWorkflowStep(Integer workflowID, Integer parentStepID, Integer currentStepID,
            String allPermissionData, Integer stepSeq) {
        WorkflowStep step = new WorkflowStep();
        step.setActionType(WorkflowStep.ACTION_TYPE_TASK_TO_DO);
        step.setAllowAssignDueDate(GlobalConstant.FALSE);
        step.setAllowAssignPriority(GlobalConstant.FALSE);
        step.setAllowStop(GlobalConstant.FALSE);
        step.setAllPermissionData(allPermissionData);
        step.setCreatorID(new Integer("1"));
        step.setReleased(false);
        step.setLoopBackALLOffset(GlobalConstant.FALSE);
        step.setOverDueType("NA");
        step.setParentStepID(parentStepID);
        step.setParentType(WorkflowStep.ACTION_TYPE_SUBMIT);
        step.setParentStepIDs(new String[] { WorkflowStep.ACTION_TYPE_SUBMIT + "-" + parentStepID });
        step.setCurrentStepID(currentStepID);
        step.setPriority("0");
        step.setStepName("this is testStep 2");
        step.setStepSeq(stepSeq);
        step.setWorkflowRecordID(workflowID);
        step.setWorkflowRule("1");
        return step;
    }

    /**
     * default return a userDelegation that a User(Source ID:1) deletated to a
     * Role(Target ID:1)
     * 
     * @return a new UserDelegation but not ID
     * @author Samlin.zhang
     */
    public static UserDelegation getUserDelegation() {
        UserDelegation delegate = new UserDelegation();
        delegate.setNotificationType("E,S");
        delegate.setSourceUserID(new Integer("1"));
        delegate.setTargetObjectID(new Integer("1"));
        delegate.setTargetObjectType(GlobalConstant.SUBJECT_TYPE_ROLE);
        delegate.setStartDate(Utility.getCurrentTimestamp());
        return delegate;
    }

    public static String getAllPermissionString() {
        String allPissimion = "-1\t6001\tRIECD\t\t\n-1\t6002\tR\t\t\n-1\t6003\tRIECDPST\t\t\n-1\t"
                + "6004\tRIECD\t\t\n-1\t6005\tR\t\t\n-1\t6007\tRIECD\t\t\n-1\t6008\tRIECD\t\t\n-1\t"
                + "6009\tRIECD\t\t\n-1\t6010\tRST\t\t\n-1\t6011\tRIECD\t\t\n-1\t6012\tRIECD\t\t\n-1\t6013\tRIED\t\t\n-1\t"
                + "6014\tRIED\t\t\n-1\t"
                + "7001\tRIECD\t\t\n-1\t7002\tR\t\t\n-1\t7004\tR\t\t\n-1\t7005\tRIECD\t\t\n-1\t7006\tRIECD\t\t\n-1\t7007\tRIECD\t\t\n-1\t"
                + "8001\tRIE\t\t\n-1\t8002\tRE\t\t\n-1\t8003\tRIEN\t\t\n-1\t8006\tRIECD\t\t\n-1\t8009\tRIECD\t\t\n-1\t8007\tRIED\t\t\n-1\t"
                + "8008\tR\t\t\n-1\t8004\tRIECD\t\t\n-1\t8005\tRIECD\t\t\n-1\t5001\tRIECD\t\t\n-1\t5002\tRE\t\t\n-1\t"
                + "4002\tRIECDP\t\t\n-1\t4003\tRIECD\t\t\n-1\t"
                + "3001\tRIECD\t\t\n-1\t3002\tRIECD\t\t\n-1\t1001\tRIECD\t\t\n-1\t1002\tRIECD\t\t\n-1\t"
                + "1003\tRIECD\t\t\n-1\t1004\tRE\t\t\n-1\t1005\tRIECD\t\t\n-1\t1006\tRE\t\t\n-1\t1007\tRP\t\t\n-1\t1008\tRIECD\t\t\n-1\t"
                + "1009\tRE\t\t\n-1\t2001\tR\t\t\n-1\t2002\tR\t\t\n-1\t2003\tRIED\t\t\n";
        return allPissimion;
    }

    public static String getWorkflowPermissionString() {
        String allPissimion = "-1\t8001\tRIE\t\t\n-1\t8002\tRE\t\t\n-1\t"
                + "8003\tRIEN\t\t\n-1\t8006\tRIECD\t\t\n-1\t8009\tRIECD\t\t\n-1\t" + "8007\tRIED\t\t\n-1\t"
                + "8008\tR\t\t\n-1\t8004\tRIECD\t\t\n-1\t8005\tRIECD\t\t\n";
        return allPissimion;
    }

    public static UserGroup getNewGroup() {
        UserGroup group = new UserGroup();
        group.setGroupName("this UnitTest new Group Name3");
        group.setGroupType(UserGroup.GROUP_TYPE_PUBLIC);
        group.setGroupDesc("this is UnitTest new Group Desc");
        group.setOwnerUserRecordID(new Integer("1"));// sessionContainer.getUserRecordID()
        return group;
    }

    public static UserRecord getNewUserRecord() {
        UserRecord user = new UserRecord();
        user.setFirstName("first name");
        user.setLastName("last name");
        user.setFailedAttempt(new Integer("3"));
        user.setFullName("first last ");
        user.setLocale(GlobalConstant.LOCALE_STR_EN_US);
        user.setLoginPwd("pass");
        user.setLoginName("loginname1");
        user.setMaxAttempt(new Integer("3"));
        user.setModifyLoginPwd("Y");
        user.setPreference(new Integer(1));
        user.setPwdExpiryDay(new Integer("3"));
        // UserRecord.USER_TYPE_STAFF means this user a new staff
        user.setUserType(UserRecord.USER_TYPE_STAFF);
        user.setStatus(GlobalConstant.STATUS_ACTIVE);
        return user;
    }

    /**
     * get a delete_all tables for workflow test
     * 
     * @return IDataSet
     * @throws IOException
     * @throws DataSetException
     * @throws FileNotFoundException
     */
    public static IDataSet getDeleteAllDataSet() throws IOException, DataSetException, FileNotFoundException {
        if (deleteAllDataset != null) {
            return deleteAllDataset;
        }

        deleteAllDataset = retrieveFileSet("/dbunit/eip318StandardDeleteAll.xml");
        return deleteAllDataset;
    }

    /**
     * @return
     * @throws IOException
     * @throws DataSetException
     * @throws FileNotFoundException
     */
    public static IDataSet getDeleteAllForBaseTestDataSet() throws IOException, DataSetException, FileNotFoundException {
        if (deleteAllForBaseTestDataSet != null) {
            return deleteAllForBaseTestDataSet;
        }

        deleteAllForBaseTestDataSet = retrieveFileSet(EIP318STANDARD_DELETE_ALL_FOR_BASE_TEST_XML);
        return deleteAllForBaseTestDataSet;
    }

    /**
     * @return
     * @throws IOException
     * @throws DataSetException
     * @throws FileNotFoundException
     */
    public static IDataSet getAllInitWorkflowEnvTestDataSet() throws IOException, DataSetException, FileNotFoundException {
        // HC: Is this intentional? if so, the null checking in next line is
        // always untrue
        // allInitWorkflowEnvTestDataSet = null;

        if (allInitWorkflowEnvTestDataSet != null) {
            return allInitWorkflowEnvTestDataSet;
        }

        allInitWorkflowEnvTestDataSet = retrieveFileSet("/dbunit/eip318Standard.xml");
        return allInitWorkflowEnvTestDataSet;
    }

    /**
     * Generate dbunit dateset for testing purpose.
     * 
     * @param filePath
     *            String of file location
     * @return Flat XML dataset
     * @throws IOException
     * @throws DataSetException
     * @throws FileNotFoundException
     */
    private static FlatXmlDataSet retrieveFileSet(String filePath) throws IOException, DataSetException, FileNotFoundException {
        FlatXmlDataSet dataSet = new FlatXmlDataSet(WFObjectFactory.class.getResourceAsStream(filePath));
        return dataSet;
    }
}
